#include "BreakPointService.h"
#include <iostream>
#include "BreakPointFile.h"
#include "BreakPointDecorator.h"

#include "IBreakPointStateEvent.h" //BreakPointStateEvent


BreakPointService::BreakPointService()
: state(BreakPointEndState::newInstance())
, breakPoint(new BreakPointDecorator(new BreakPointFile("./seqNo.bin")))
{
}
BreakPointService::~BreakPointService()
{
    if(breakPoint != nullptr){
        delete breakPoint;
        breakPoint = nullptr;
    }
    state = nullptr;
}

const IBreakPointStateEvent & BreakPointService::getState() const{
    return *state;
}

void BreakPointService::setState(IBreakPointStateEvent * state){
    if(this->state != state)
        this->state = state;
}


int BreakPointService::loadFromFile(){
    std::cout << "BreakPointService::loadFromFile breakPoint:"  << std::endl;
    std::cout   << breakPoint->get() << std::endl;
    return 0;
}

int BreakPointService::saveToFile(){
    std::cout << "BreakPointService::saveToFile " << std::endl;
    breakPoint->set(breakPoint->get());//save the mem seqNo to file
    return 0;
}


int BreakPointService::login(){
    std::cout << "BreakPointService::login::sendMessage-login-req" << std::endl;
    return sendMessageAction("login-req");
}

int BreakPointService::logDisconnected(){
    std::cout << "BreakPointService::disconnectedAction " << std::endl;
    return 0;
}

int BreakPointService::handleLoginResp(const char * msg){
    std::cout << "BreakPointService::receivedLoginRespAction :[" << msg << "]" << std::endl;
    return 0;
}
int BreakPointService::handleNormalResp(const char * msg){
    std::cout << "BreakPointService::receivedNormalRespAction :[" << msg << "]" << std::endl;
    return 0;
}
int BreakPointService::handleBreakPointResp(const char * msg){
    std::cout << "BreakPointService::receivedBreakPointRespAction :[" << msg << "]" << std::endl;
    breakPoint->add(1); //fake action
    return 0;
}

int BreakPointService::sendMessageAction(const char * msg){
    std::cout << "BreakPointService::sendMessageAction : [" << msg << "] " << std::endl;
    return 0;
}

int BreakPointService::queryBreakPoint(){
    std::cout << "BreakPointService::queryBreakPoint " << std::endl;

    if(0 !=sendMessageAction("breakPoint-req")){
        std::cout << "send message failed" << std::endl;
        return -1;
    }
    return 0;
}





int BreakPointService::start(){
    std::cout << "BreakPointService::start " << std::endl;

    if(0 != state->start(this)){
        std::cout << "switch to Inited status failed : ";
        state->log(std::cout) << std::endl;
        return -1;
    }
    return 0;
}

int BreakPointService::stop(){
    std::cout << "BreakPointService::stop to: " << breakPoint->get() << std::endl;

    // save seqNo from mem into file
    if(0 != state->stop(this)){
        std::cout << "Error: state stop error" << std::endl;
        state->log(std::cout) << std::endl;
        return -1;
    }
    return 0;
}

int BreakPointService::connected(){
    std::cout << "BreakPointService::connected " << std::endl;
    //switch to Connected Status and then sendMessage
    if(0 != state->connected(this)){
        std::cout << "Error: state connect error" << std::endl;
        state->log(std::cout) << std::endl;
        return -1;
    }
    return 0;
}
int BreakPointService::disconnected(){
    if(0 != state->disconnected(this)){
        std::cout << "Error: state disconnect error" << std::endl;
        state->log(std::cout) << std::endl;
        return -1;
    }
    return 0;
}

int BreakPointService::timeout(){
    std::cout << "BreakPointService::timeout "
        <<"-> query the data [" <<  breakPoint->get()+1 <<  ", MAX)" << std::endl;

    if(0 != state->timeout(this)){
        std::cout << "Error: state timeout error" << std::endl;
        state->log(std::cout) << std::endl;
        return -1;
    }
    return 0;
}


int BreakPointService::receivedLoginResp(const char * msg){
    std::cout << "BreakPointService::receive :[" << msg << "]" 
        << "\n\tswitch to [login] status if response ok" 
        << std::endl;

    if(0 != state->receivedLoginResp(this, msg)){
        std::cout << "Error: state receivedLoginResp error" << std::endl;
        state->log(std::cout) << std::endl;
        return -1;
    }
    return 0;
}

int BreakPointService::receivedBreakPointResp(const char * msg){
    std::cout << "BreakPointService::receive :[" << msg << "]" << std::endl;

    if(0 != state->receivedBreakPointResp(this, msg)){
        std::cout << "Error: state receivedBreakPointResp error" << std::endl;
        state->log(std::cout) << std::endl;
        return -1;
    }
    return 0;
}

int BreakPointService::receivedNormalResp(const char * msg){
    std::cout << "BreakPointService::receive :[" << msg << "]" << std::endl;

    if(0 != state->receivedNormalResp(this, msg)){
        std::cout << "Error: received normal rsp failed " << std::endl;
        state->log(std::cout) << std::endl;
        return -1;
    }
    return 0;
}

int BreakPointService::sendMessage(const char * msg){
    if(0 != state->sendMessage(this, msg)){
        std::cout << "Error: sendMessage failed, msg:" << msg << std::endl;
        state->log(std::cout) << std::endl;
        return -1;
    }
    state->log(std::cout) << std::endl;
    return 0;
}
